package clustering;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
public class Cluster_Similarity_by_PairwiseModel {
	private double similarities[];
	private int article_size;
	
	public Cluster_Similarity_by_PairwiseModel(int size){
		article_size = size;
		similarities = new double[article_size*(article_size-1)/2];
	}
	
	public void ReadPairwise_Model_Similarities(String filename)
	{
		File f = new File(filename);
		FileInputStream fis;
		try{
			fis = new FileInputStream(f);
			InputStreamReader isr=new InputStreamReader(fis);
			BufferedReader br=new BufferedReader(isr);
			String line = br.readLine();
			while(line != null)
			{
				line = line.trim();
				if(line.length()>0)
				{
					String s[] = line.split("\t");
					int index1 = Integer.valueOf(s[0]);
					int index2 = Integer.valueOf(s[1]);
					float value = Float.valueOf(s[2]);
					int index = 0;
					if(index1<= index2)
						index = article_size*(article_size-1)/2 - (article_size -index1)*(article_size-index1-1)/2 + index2 - index1 -1;
					else
						index = article_size* (article_size-1)/2 - (article_size-index2)* (article_size- index2 -1)/2 + index1 - index2 -1;
					similarities[index] = value;
				}
				line = br.readLine();
			}
			br.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
	}
	class cluster{
		public int index;
		public List<Integer> members;
		public cluster(String line)
		{
			
			String s[] = line.split(" ");
			members = new ArrayList<Integer>(s.length-1);
			index = Integer.valueOf(s[0].substring(1,s[0].length()-1));
			for(int i=1; i<s.length;i++)
				members.add(Integer.valueOf(s[i]));
		}
	};
	public void Write_Cluster_Similarity(String writefile)
	{
		File f = new File(writefile);
		OutputStreamWriter write;
		try{
			write = new OutputStreamWriter(new FileOutputStream(f,false));
			BufferedWriter bw =new BufferedWriter(write);
			for(int i=0; i<clusters.size();i++)
				for(int j=i+1; j<clusters.size();j++)
				{
					//compute the clusters' similarity.
					double sim = Get_Cluster_Similarity(i,j);
					bw.write(String.valueOf(i)+"\t"+String.valueOf(j)+"\t"+String.valueOf(sim));
					bw.newLine(); 
				}
			bw.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
		
	}
	public List<cluster> clusters = new ArrayList<cluster>();
	public void ReadClusters(String filename)
	{
		File f = new File(filename);
		FileInputStream fis;
		try{
			fis = new FileInputStream(f);
			InputStreamReader isr=new InputStreamReader(fis);
			BufferedReader br=new BufferedReader(isr);
			String line = br.readLine();
      int count = 0;
			while(line != null)
			{
				if(line.length()>0)
				{
					cluster c = new cluster(line);
          c.index = count++;
					clusters.add(c);
				}
				line = br.readLine();
			}
			br.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
	};
	
	public double Get_Cluster_Similarity(int index1, int index2)
	{
		double sim = 0.0;
		int count = 0;
		for(int i=0; i<clusters.get(index1).members.size();i++)
			for(int j=0; j<clusters.get(index2).members.size();j++){
				int unit1 = clusters.get(index1).members.get(i);
				int unit2 = clusters.get(index2).members.get(j);
				int index = -1;
				if(unit1 <= unit2)
					index = article_size*(article_size-1)/2 - (article_size - unit1)*(article_size-unit1 -1)/2 + unit2 - unit1 -1;
				else
					index = article_size*(article_size-1)/2 - (article_size - unit2)*(article_size - unit2 -1)/2 + unit1 - unit2 -1;
				if(index>=0)
					sim += similarities[index];
				else
					try {
						throw new Exception("cannot find similarities"+ unit1+"\t"+unit2);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				count++;
			}
		sim = sim/count;
		return sim;
	}
}
